<script setup lang="ts">
import { Fragment, h, nextTick, onBeforeMount, ref } from "vue";
import { useColumns } from "./columns";
import { IconifyIconOnline } from "@/components/ReIcon";
import { PlusDialogForm } from "plus-pro-components";
import type { PlusColumn, PlusDialogFormInstance } from "plus-pro-components";
import { message } from "@/utils/message";
import { ElImage, ElUpload } from "element-plus";
import { UPLOAD_IMAGE_URL } from "@/api/images";
import { ImageItem } from "types/image";
import RichTextEditor from "@/components/RichTextEditor";
import { createArticle, deleteArticle, updateArticle } from "@/api/article";

const SERVER_URL = import.meta.env.VITE_SERVER_URL;

const tableRef = ref();

const {
  loading,
  columns,
  dataList,
  pagination,
  loadingConfig,
  adaptiveConfig,
  searchText,
  onSizeChange,
  onCurrentChange,
  refresh,
  search
} = useColumns({
  onEdit: (row, index) => {
    formData.value = {
      id: row.id,
      title: row.title,
      abstract: row.abstract,
      tags: row.tags,
      cover: row.cover,
      content: row.content
    };
    formVisible.value = true;
  },
  onDelete: async (row, index) => {
    try {
      await deleteArticle(row.id);
      message("删除成功", { type: "success" });
      refresh();
    } catch (e) {
      if (e.response.data && e.response.data.message) {
        message(e.response.data.message, { type: "error" });
      } else {
        message("删除失败", { type: "error" });
      }
      console.log(e);
    }
  }
});

const formRules = {
  title: [
    {
      required: true,
      message: "请输入文章标题"
    }
  ],
  content: [
    {
      required: true,
      message: "请输入内容"
    }
  ]
};

onBeforeMount(async () => {});

const submitLoading = ref<boolean>(false);
const formRef = ref<PlusDialogFormInstance | null>(null);
const formColumns: PlusColumn[] = [
  {
    label: "文章标题",
    prop: "title",
    valueType: "input"
  },
  {
    label: "文章摘要",
    prop: "abstract",
    valueType: "textarea"
  },
  {
    label: "文章标签",
    prop: "tags",
    valueType: "plus-input-tag"
  },
  {
    label: "文章封面",
    prop: "cover",
    valueType: "img",
    renderField(value: string, onChange) {
      return h(Fragment, [
        h(
          ElUpload,
          {
            action: UPLOAD_IMAGE_URL,
            listType: "picture-card",
            showFileList: false,
            onSuccess: async (data: ImageItem) => {
              onChange(
                `/static/images/${data.folder}/${data.hash}.${data.format}`
              );
              nextTick(() => {
                formRef.value.formInstance.validateField(["cover"]);
              });
            },
            class: "article-cover-upload"
          },
          () => {
            if (value) {
              return h(ElImage, {
                src: SERVER_URL + value,
                fit: "cover",
                style: "width:100%; height:100%"
              });
            } else {
              return h(IconifyIconOnline, { icon: "ep:plus" });
            }
          }
        )
      ]);
    }
  },
  {
    label: "文章内容",
    prop: "content",
    renderField(_, onChange) {
      return h(Fragment, [
        h(RichTextEditor, {
          modelValue: formData.value.content,
          "onUpdate:modelValue": e => {
            onChange(e);
          }
        })
      ]);
    }
  }
];
const formVisible = ref(false);
const formData = ref<{
  id?: number;
  title: string;
  abstract?: string;
  tags?: string[];
  cover?: string;
  content: string;
}>({ title: "", content: "" });

const handleNew = () => {
  formData.value = {
    title: "",
    content: ""
  };
  formVisible.value = true;
};

const handleConfirm = async e => {
  try {
    submitLoading.value = true;
    if (formData.value.id) {
      await updateArticle(e);
    } else {
      await createArticle(e);
    }
    message("保存成功", { type: "success" });
    formVisible.value = false;
    refresh();
  } catch (e) {
    if (e.response.data && e.response.data.message) {
      message(e.response.data.message, { type: "error" });
    } else {
      message("保存失败", { type: "error" });
    }
    console.log(e);
  } finally {
    submitLoading.value = false;
  }
};

const handleSearch = e => {
  search();
};
</script>
<template>
  <div>
    <el-card shadow="never">
      <template #header>
        <div class="flex justify-between items-center">
          <span>文章管理</span>

          <el-space>
            <el-input
              v-model="searchText"
              style="width: 240px"
              clearable
              placeholder="请输入关键词"
              @change="handleSearch"
            >
              <template #append>
                <IconifyIconOnline icon="ep:search" />
              </template>
            </el-input>
            <el-button type="primary" @click="handleNew">
              <template #icon>
                <IconifyIconOnline icon="ep:plus" />
              </template>
              新增
            </el-button>
          </el-space>
        </div>
      </template>
      <pure-table
        ref="tableRef"
        border
        adaptive
        :adaptiveConfig="adaptiveConfig"
        row-key="id"
        alignWhole="center"
        showOverflowTooltip
        :loading="loading"
        :loading-config="loadingConfig"
        :data="dataList"
        :columns="columns"
        :pagination="pagination"
        @page-size-change="onSizeChange"
        @page-current-change="onCurrentChange"
      />
    </el-card>
    <PlusDialogForm
      ref="formRef"
      v-model:visible="formVisible"
      v-model="formData"
      :destroy-on-close="true"
      :title="formData.id ? '编辑文章' : '添加文章'"
      :form="{
        columns: formColumns,
        rules: formRules,
        labelPosition: 'top',
        rowProps: {
          gutter: 12
        }
      }"
      :confirmLoading="submitLoading"
      @confirm="handleConfirm"
    />
  </div>
</template>
<style scoped lang="scss">
:deep(.article-cover-upload) {
  .el-upload--picture-card {
    width: 320px;
    overflow: hidden;
  }
}
</style>
